﻿using Common;
using Orleans;
using Orleans.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Server.Impl
{
    /// <summary>
    /// AGV信息集合。不需要在UI上展示的可以不使用本Grain
    /// 由于AGV在开机后会不断的上报数据，所以数据不用做缓存
    /// </summary>
    public class AgvSetImpl : Grain, IAgvSet
    {
        private readonly List<AgvItem> list = new List<AgvItem>();

        private readonly IPersistentState<List<AgvDeviceRel>> cache;

        public AgvSetImpl([PersistentState("agvDevice", "redisStorage")] IPersistentState<List<AgvDeviceRel>> persistent)
        {
            this.cache = persistent;
        }

        public override async Task OnActivateAsync()
        {
            await cache.ReadStateAsync();
            await base.OnActivateAsync();
        }



        public Task 更新AGV信息(long AgvID, Agv状态 状态, int X, int Y)
        {
            var item = list.Find(x => x.AgvID == AgvID);
            if (item == null)
            {
                //新加入的AGV
                item = new AgvItem()
                {
                    AgvID = AgvID,
                    Status = (int)状态,
                    X = X,
                    Y = Y,
                    LastTime = DateTime.Now,
                };
                list.Add(item);
            }
            else
            {
                //原有AGV
                item.Status = (int)状态;
                item.X = X;
                item.Y = Y;
                item.LastTime = DateTime.Now;
            }
            return Task.CompletedTask;
        }

        public Task<List<AGV位置>> 获取所有AGV的位置()
        {
            //30秒之前的，应该出故障了
            DateTime t = DateTime.Now.AddSeconds(-30);
            List<AGV位置> re = new List<AGV位置>();
            list.ForEach(item =>
            {
                if (item.LastTime >= t)
                {
                    //30秒内有活动的
                    re.Add(new AGV位置()
                    {
                        AgvID = item.AgvID,
                        X = item.X,
                        Y = item.Y,
                        Status = item.Status,
                    });
                }
            });
            return Task.FromResult(re);
        }


        public async Task 更新AGV占用传输机台(long AgvID,  string DeviceID,string MarkerID )
        {
            var obj = cache.State.Find(x => x.AgvID == AgvID);
            if (obj != null && obj.DeviceID != DeviceID)
            {
                obj.DeviceID = DeviceID;
                obj.MarkerID = MarkerID;
                await cache.WriteStateAsync();
            }
        }

        public Task<long> 获取传输机台处的AGV(string DeviceID)
        {
            var obj = cache.State.Find(x => x.DeviceID == DeviceID);
            if (obj != null  )
            {
                return Task.FromResult(obj.AgvID);
            }
            else
            {
                return Task.FromResult(0L);
            }

        }

 
        /// <summary>
        /// list为地标号
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public   Task<List<string>> 过滤占用机台(List<string> list)
        {
            List<string> re=new List<string>();
            list.ForEach(markerid =>
            {
                if (cache.State.Any(x => x.MarkerID == markerid) == false)
                {
                    re.Add(markerid);
                }
            }); 
            return Task.FromResult(re);
        }
    }



    #region 数据定义

    public class AgvItem
    {
        public long AgvID { get; set; }
        public int Status { get; set; }
        public int X { get;set; }
        public int Y { get;set; } 
         
        public DateTime  LastTime { get; set; } 
    }


    public class AgvDeviceRel
    {
        public long AgvID { get; set; }
        public string DeviceID { get; set; } = "";
        public string MarkerID { get; set; } = "";
    }
    #endregion
}
